﻿using Sl.Upload.Help;
using Sl.Upload.Interface;
using Sl.Upload.Models;
using Sl.Upload.Tool;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Sl.Upload
{
    public class Upload
    {
        IStoragePath _storagePath;
        IThumbanailRule _thumbnailRule;
        public Upload(IStoragePath storagePath, IThumbanailRule thumbnailRule)
        {
            _storagePath = storagePath;
            _thumbnailRule = thumbnailRule;
        }

        public CompleteInfo UploadFile(HttpPostedFile file, PostFileParam pfp, List<CutRule> cutRuleList)
        {
            FilePath filePath = _storagePath.GetPath(pfp);
            List<CutInfo> cutList = null;
            CompleteInfo comp = new CompleteInfo();
            if (pfp.Command == CommandType.Upload)
            {
                bool isImage = false;
                if (pfp.UploadType == UploadType.Image)
                    isImage = true;
                else if (pfp.UploadType == UploadType.File)
                    isImage = false;
                else
                    isImage = OtherHelp.IsImage(file.InputStream);
                IUpload iUpload = UploadFactory.Creater(isImage);
                FileInfoModel model = Assembly(file, filePath, cutList);
                model.Chunk = pfp.Chunk;
                model.Chunks = pfp.Chunks;
                model.Guid = pfp.Guid;
                if (isImage)
                    model.CutItem = new Thumbnail().GetThumbnail(pfp.UploadPathType, cutRuleList, filePath.SavePath, _thumbnailRule);
                comp = iUpload.Upload(model);
            }
            else if (pfp.Command == CommandType.Merge)
            {
                FileInfoModel model = new FileInfoModel()
                {
                    SavePath = filePath.SavePath,
                    Guid = pfp.Guid,
                    UrlPath= filePath.UrlPath,
                    OriginalName = pfp.FileName,
                    FileSuffix = Path.GetExtension(pfp.FileName)
                };
                comp = MergeFile(model);
            }
            return comp;
        }

        /// <summary>
        /// 组装上传参数
        /// </summary>
        /// <param name="file"></param>
        /// <param name="filePath"></param>
        /// <param name="cutList"></param>
        /// <returns></returns>
        private FileInfoModel Assembly(HttpPostedFile file, FilePath filePath, List<CutInfo> cutList)
        {
            FileInfoModel fim = new FileInfoModel();
            fim.StreamInfo = file.InputStream;
            byte[] byteFiless = new byte[file.InputStream.Length];
            file.InputStream.Read(byteFiless, 0, byteFiless.Length);
            fim.FileByte = byteFiless;
            fim.UploadName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
            fim.OriginalName = file.FileName;
            fim.ContentLength = file.ContentLength;
            fim.FileSuffix = Path.GetExtension(file.FileName);
            fim.SavePath = filePath.SavePath;
            fim.UrlPath = filePath.UrlPath;
            fim.CutItem = cutList;
            return fim;
        }

        private CompleteInfo MergeFile(FileInfoModel fim)
        {
            CompleteInfo ci = new CompleteInfo();
            string path = fim.SavePath + "\\" + fim.Guid;
            DirectoryInfo di = new DirectoryInfo(path);
            int fileCount = di.GetFiles().Count();
            string fileName = fim.SavePath + "\\" + fim.Guid + fim.FileSuffix;
            if (!File.Exists(fileName))
            {
                FileStream addFile = new FileStream(fileName, FileMode.Append, FileAccess.Write);
                BinaryWriter AddWriter = new BinaryWriter(addFile);
                try
                {
                    for (var i = 0; i < fileCount; i++)
                    {
                        AddWriter.Write(File.ReadAllBytes(path + "\\" + i));
                    }
                }
                catch (Exception ex)
                {
                    ci.UploadStatus = UploadStatus.Error;
                    ci.ErrorMessage = ex.Message;
                    return ci;
                }
                finally
                {
                    AddWriter.Close();
                    AddWriter.Dispose();
                    addFile.Close();
                    addFile.Dispose();
                }
            }
            di.Delete(true);
            ci.UploadStatus = UploadStatus.Success;
            ci.Name = fim.OriginalName;
            ci.Url = fim.UrlPath + "/" + fim.Guid + fim.FileSuffix;
            ci.Size = 0;
            ci.Suffix = fim.FileSuffix;
            return ci;
        }
    }
}
